home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 140
/
Gekkan Dennou Club - 2000.1 Vol. 140 (Japan).7z
/
Gekkan Dennou Club - 2000.1 Vol. 140 (Japan) (Track 1).bin
/
tools
/
has060
/
k_macro.mac
< prev
next >
Wrap
Text File
|
1998-02-08
|
15KB
|
757 lines
.nlist
.ifndef __MACRO_MAC__
__MACRO_MAC__ equ 0
;----------------------------------------------------------------
;
; 構造化マクロ定義 for HAS060.X
; 1998.02.08 by M.Kamada
;
; HAS060.X v3.09+59 以降で使用できます。
;
; ifcc~elseifcc(elifcc)~else~endif 条件ブロック
;
; repeat~untilcc 後ろ判定ループ
; do~whilecc 後ろ判定ループ
; whilecc~endwhile 前判定ループ
;
; break ループ脱出
; breakcc ループ脱出(条件付き)
; continue ループ条件へジャンプ
; continuecc ループ条件へジャンプ(条件付き)
;
;----------------------------------------------------------------
;----------------------------------------------------------------
;
; 変数(ユーザは参照禁止)
;
; ~km_s_condN 条件用のスタック(2個ずつ使う)
; (+0=else,+1=endif)
; ~km_s_loopN ループ用のスタック(3個ずつ使う)
; (+0=ループの先頭,+1=continue,+2=break)
; ~km_s_repeatN repeat~untilcc用のスタック(1個ずつ使う)
; (ループの先頭のラベルの番号)
; ~km_s_doN do~whilecc用のスタック(1個ずつ使う)
; (ループの先頭のラベルの番号)
; ~km_s_whileN whilecc~endwhile用のスタック(1個ずつ使う)
; (ループの先頭のラベルの番号)
;
; ~km_l_cond 条件のネスティングレベル(0~)
; ~km_l_loop ループのネスティングレベル(0~)
; ~km_l_repeat repeat~untilccのネスティングレベル(0~)
; ~km_l_do do~whileccのネスティングレベル(0~)
; ~km_l_while whilecc~endwhileのネスティングレベル(0~)
;
; ~km_n 次に使うラベルの番号(常にインクリメント)
;
; ~km_i 汎用
; ~km_j 汎用
;
;----------------------------------------------------------------
;
; ラベル(ユーザは参照禁止)
;
; ~km_aN 共通ラベル
;
;----------------------------------------------------------------
;
; マクロ(ユーザは使用禁止)
;
; ~km_push t,d,p0,p1,p2
; スタックの先頭にデータをプッシュする
; t タイプ(_cond,_loop,_repeat,_do,_while)
; d 深さ
; p0 スタックの先頭に置くデータ
; p1 スタックの先頭+1に置くデータ
; p2 スタックの先頭+2に置くデータ
;
; ~km_pop t,d スタックの先頭のデータを捨てる
; t タイプ(_cond,_loop,_repeat,_do,_while)
; d 深さ
;
;----------------------------------------------------------------
;----------------------------------------------------------------
;
; 初期化
;
;----------------------------------------------------------------
;マクロの構造上,スタックの先頭を初期化しておく必要がある
~km_s_cond0:=0 ;条件用のスタック(2個ずつ使う)
~km_s_loop0:=0 ;ループ用のスタック(3個ずつ使う)
~km_s_repeat0:=0 ;repeat~untilcc用のスタック(1個ずつ使う)
~km_s_do0:=0 ;do~whilecc用のスタック(1個ずつ使う)
~km_s_while0:=0 ;whilecc~endwhile用のスタック(1個ずつ使う)
;ネスティングレベルの初期化
~km_l_cond:=0 ;条件のネスティングレベル(0~)
~km_l_loop:=0 ;ループのネスティングレベル(0~)
~km_l_repeat:=0 ;repeat~untilccのネスティングレベル(0~)
~km_l_do:=0 ;do~whileccのネスティングレベル(0~)
~km_l_while:=0 ;whilecc~endwhileのネスティングレベル(0~)
;ラベルの番号の初期化
~km_n:=1 ;次に使うラベルの番号(常にインクリメント)
;----------------------------------------------------------------
;
; スタック操作マクロ
;
;----------------------------------------------------------------
~km_push .macro t,d,p0,p1,p2
~km_i:=~km_l&t-1
.rept ~km_l&t
~km_j:=~km_i+d
~km_s&t%~km_j:=~km_s&t%~km_i
~km_i:=~km_i-1
.endm
~km_l&t:=~km_l&t+d
.if d>=1
~km_j:=0
~km_s&t%~km_j:=p0
.endif
.if d>=2
~km_j:=1
~km_s&t%~km_j:=p1
.endif
.if d>=3
~km_j:=2
~km_s&t%~km_j:=p2
.endif
.endm
~km_pop .macro t,d
~km_l&t:=~km_l&t-d
~km_i:=d
.rept ~km_l&t
~km_j:=~km_i-d
~km_s&t%~km_j:=~km_s&t%~km_i
~km_i:=~km_i+1
.endm
.endm
;----------------------------------------------------------------
; ifcc~elseifcc(elifcc)~else~endif 条件ブロック
;
; ifcc <命令>,…
; :
; elseifcc <命令>,…
; :
; else
; :
; endif
;
; 条件が満たされているブロックだけを実行するようなコードを生成します.
; elseifccはelifccと省略できます.
;
; 生成される構造:
; <命令>,…
; JBNcc else1
; :
; JBRA endif
; else1: <命令>,…
; JBNcc else2
; :
; JBRA endif
; else2: :
; endif:
;
; 条件になる命令は,
; <~>で囲って指定します.
; 複数の命令を記述できます(0個以上10個以下).
; 最後の命令を通過した直後の状態に従って分岐します.
;----------------------------------------------------------------
.irp %cc,t,f,hi,ls,cc,hs,cs,lo,ne,nz,eq,ze,vc,vs,pl,mi,ge,lt,gt,le
if%cc .macro op0,op1,op2,op3,op4,op5,op6,op7,op8,op9
.sizem sz
~km_push _cond,2,~km_n,~km_n+1
~km_n:=~km_n+2
op0
op1
op2
op3
op4
op5
op6
op7
op8
op9
.if '%cc'='t'
.elseif '%cc'='f'
jbra&&sz ~km_a%~km_s_cond0
.else
jbn%cc&&sz ~km_a%~km_s_cond0
.endif
.endm
ifn%cc .macro op0,op1,op2,op3,op4,op5,op6,op7,op8,op9
.sizem sz
~km_push _cond,2,~km_n,~km_n+1
~km_n:=~km_n+2
op0
op1
op2
op3
op4
op5
op6
op7
op8
op9
.if '%cc'='t'
jbra&&sz ~km_a%~km_s_cond0
.elseif '%cc'='f'
.else
jb%cc&&sz ~km_a%~km_s_cond0
.endif
.endm
elseif%cc .macro op0,op1,op2,op3,op4,op5,op6,op7,op8,op9
.sizem sz
.if ~km_l_cond=0
.fail 1 ;elseifに対応するifがない
.exitm
.endif
jbra&&sz ~km_a%~km_s_cond1
~km_a%~km_s_cond0:
~km_s_cond0:=~km_n
~km_n:=~km_n+1
op0
op1
op2
op3
op4
op5
op6
op7
op8
op9
.if '%cc'='t'
.elseif '%cc'='f'
jbra&&sz ~km_a%~km_s_cond0
.else
jbn%cc&&sz ~km_a%~km_s_cond0
.endif
.endm
elseifn%cc .macro op0,op1,op2,op3,op4,op5,op6,op7,op8,op9
.sizem sz
.if ~km_l_cond=0
.fail 1 ;elseifに対応するifがない
.exitm
.endif
jbra&&sz ~km_a%~km_s_cond1
~km_a%~km_s_cond0:
~km_s_cond0:=~km_n
~km_n:=~km_n+1
op0
op1
op2
op3
op4
op5
op6
op7
op8
op9
.if '%cc'='t'
jbra&&sz ~km_a%~km_s_cond0
.elseif '%cc'='f'
.else
jb%cc&&sz ~km_a%~km_s_cond0
.endif
.endm
elif%cc .macro op0,op1,op2,op3,op4,op5,op6,op7,op8,op9
.sizem sz
.if ~km_l_cond=0
.fail 1 ;elseifに対応するifがない
.exitm
.endif
jbra&&sz ~km_a%~km_s_cond1
~km_a%~km_s_cond0:
~km_s_cond0:=~km_n
~km_n:=~km_n+1
op0
op1
op2
op3
op4
op5
op6
op7
op8
op9
.if '%cc'='t'
.elseif '%cc'='f'
jbra&&sz ~km_a%~km_s_cond0
.else
jbn%cc&&sz ~km_a%~km_s_cond0
.endif
.endm
elifn%cc .macro op0,op1,op2,op3,op4,op5,op6,op7,op8,op9
.sizem sz
.if ~km_l_cond=0
.fail 1 ;elseifに対応するifがない
.exitm
.endif
jbra&&sz ~km_a%~km_s_cond1
~km_a%~km_s_cond0:
~km_s_cond0:=~km_n
~km_n:=~km_n+1
op0
op1
op2
op3
op4
op5
op6
op7
op8
op9
.if '%cc'='t'
jbra&&sz ~km_a%~km_s_cond0
.elseif '%cc'='f'
.else
jb%cc&&sz ~km_a%~km_s_cond0
.endif
.endm
.endm
else .macro
.sizem sz
.if ~km_l_cond=0
.fail 1 ;elseに対応するifがない
.exitm
.endif
.if ~km_s_cond0=0
.fail 1 ;elseが重複している
.exitm
.endif
jbra&sz ~km_a%~km_s_cond1
~km_a%~km_s_cond0:
~km_s_cond0:=0
.endm
endif .macro
.if ~km_l_cond=0
.fail 1 ;endifに対応するifがない
.exitm
.endif
.if ~km_s_cond0
~km_a%~km_s_cond0:
.endif
~km_a%~km_s_cond1:
~km_pop _cond,2
.endm
;----------------------------------------------------------------
; repeat~untilcc 後ろ判定ループ
;
; repeat
; :
; untilcc <命令>,…
;
; 条件が満たされるまでループするようなコードを生成します.
; do~whileccとは条件が逆になります.
;
; 生成される構造:
; loop:
; :
; continue:
; <命令>,…
; JBNcc loop
; break:
;
; 条件になる命令は,
; <~>で囲って指定します.
; 複数の命令を記述できます(0個以上10個以下).
; 最後の命令を通過した直後の状態に従って分岐します.
;----------------------------------------------------------------
repeat .macro
~km_push _loop,3,~km_n,~km_n+1,~km_n+2
~km_n:=~km_n+3
~km_a%~km_s_loop0:
~km_push _repeat,1,~km_s_loop0
.endm
.irp %cc,t,f,hi,ls,cc,hs,cs,lo,ne,nz,eq,ze,vc,vs,pl,mi,ge,lt,gt,le
until%cc .macro op0,op1,op2,op3,op4,op5,op6,op7,op8,op9
.sizem sz
.if ~km_l_repeat=0
.fail 1 ;untilccに対応するrepeatがない
.exitm
.endif
.if ~km_s_repeat0<>~km_s_loop0
.fail 1 ;repeat~untilccの対応がおかしい
.exitm
.endif
~km_pop _repeat,1
~km_a%~km_s_loop1:
op0
op1
op2
op3
op4
op5
op6
op7
op8
op9
.if '%cc'='t'
.elseif '%cc'='f'
jbra&&sz ~km_a%~km_s_loop0
.else
jbn%cc&&sz ~km_a%~km_s_loop0
.endif
~km_a%~km_s_loop2:
~km_pop _loop,3
.endm
untiln%cc .macro op0,op1,op2,op3,op4,op5,op6,op7,op8,op9
.sizem sz
.if ~km_l_repeat=0
.fail 1 ;untilccに対応するrepeatがない
.exitm
.endif
.if ~km_s_repeat0<>~km_s_loop0
.fail 1 ;repeat~untilccの対応がおかしい
.exitm
.endif
~km_pop _repeat,1
~km_a%~km_s_loop1:
op0
op1
op2
op3
op4
op5
op6
op7
op8
op9
.if '%cc'='t'
jbra&&sz ~km_a%~km_s_loop0
.elseif '%cc'='f'
.else
jb%cc&&sz ~km_a%~km_s_loop0
.endif
~km_a%~km_s_loop2:
~km_pop _loop,3
.endm
.endm
;----------------------------------------------------------------
; do~whilecc 後ろ判定ループ
;
; do
; :
; whilecc <命令>,…
;
; 条件が満たされている間だけループするようなコードを生成します.
; repeat~untilccとは条件が逆になります.
;
; 生成される構造:
; loop:
; :
; continue:
; <命令>,…
; JBcc loop
; break:
;
; 条件になる命令は,
; <~>で囲って指定します.
; 複数の命令を記述できます(0個以上10個以下).
; 最後の命令を通過した直後の状態に従って分岐します.
;----------------------------------------------------------------
; whilecc~endwhile 前判定ループ
;
; whilecc <命令>,…
; :
; endwhile
;
; 条件が満たされている間だけループするようなコードを生成します.
;
; 生成される構造:
; loop:
; continue:
; <命令>,…
; JBNcc break
; :
; JBRA loop
; break:
;
; マクロの構造の都合で,
; 条件判定をループの末尾に配置するような生成方法にはなっていません.
;
; 条件になる命令は,
; <~>で囲って指定します.
; 複数の命令を記述できます(0個以上10個以下).
; 最後の命令を通過した直後の状態に従って分岐します.
;----------------------------------------------------------------
do .macro
~km_push _loop,3,~km_n,~km_n+1,~km_n+2
~km_n:=~km_n+3
~km_a%~km_s_loop0:
~km_push _do,1,~km_s_loop0
.endm
.irp %cc,t,f,hi,ls,cc,hs,cs,lo,ne,nz,eq,ze,vc,vs,pl,mi,ge,lt,gt,le
while%cc .macro op0,op1,op2,op3,op4,op5,op6,op7,op8,op9
.sizem sz
.if (~km_l_do=0).or.(~km_s_do0<>~km_s_loop0)
;whileccに対応するdoがない,または,do~whileccの対応がおかしいとき,
;whilecc~endwhileと認識する
~km_push _loop,3,~km_n,~km_n+1,~km_n+2
~km_n:=~km_n+3
~km_a%~km_s_loop0:
~km_a%~km_s_loop1:
op0
op1
op2
op3
op4
op5
op6
op7
op8
op9
.if '%cc'='t'
.elseif '%cc'='f'
jbra&&sz ~km_a%~km_s_loop2
.else
jbn%cc&&sz ~km_a%~km_s_loop2
.endif
~km_push _while,1,~km_s_loop0
.else
;do~whileccのとき
~km_pop _do,1
~km_a%~km_s_loop1:
op0
op1
op2
op3
op4
op5
op6
op7
op8
op9
.if '%cc'='t'
jbra&&sz ~km_a%~km_s_loop0
.elseif '%cc'='f'
.else
jb%cc&&sz ~km_a%~km_s_loop0
.endif
~km_a%~km_s_loop2:
~km_pop _loop,3
.endif
.endm
whilen%cc .macro op0,op1,op2,op3,op4,op5,op6,op7,op8,op9
.sizem sz
.if (~km_l_do=0).or.(~km_s_do0<>~km_s_loop0)
;whileccに対応するdoがない,または,do~whileccの対応がおかしいとき,
;whilecc~endwhileと認識する
~km_push _loop,3,~km_n,~km_n+1,~km_n+2
~km_n:=~km_n+3
~km_a%~km_s_loop0:
~km_a%~km_s_loop1:
op0
op1
op2
op3
op4
op5
op6
op7
op8
op9
.if '%cc'='t'
.elseif '%cc'='f'
jbra&&sz ~km_a%~km_s_loop2
.else
jb%cc&&sz ~km_a%~km_s_loop2
.endif
~km_push _while,1,~km_s_loop0
.else
;do~whileccのとき
~km_pop _do,1
~km_a%~km_s_loop1:
op0
op1
op2
op3
op4
op5
op6
op7
op8
op9
.if '%cc'='t'
.elseif '%cc'='f'
jbra&&sz ~km_a%~km_s_loop0
.else
jbn%cc&&sz ~km_a%~km_s_loop0
.endif
~km_a%~km_s_loop2:
~km_pop _loop,3
.endif
.endm
.endm
endwhile .macro
.sizem sz
.if ~km_l_while=0
.fail 1 ;endwhileに対応するwhileがない
.exitm
.endif
.if ~km_s_while0<>~km_s_loop0
.fail 1 ;while~endwhileの対応がおかしい
.exitm
.endif
~km_pop _while,1
jbra&sz ~km_a%~km_s_loop0
~km_a%~km_s_loop2:
~km_pop _loop,3
.endm
;----------------------------------------------------------------
; break ループ脱出
;
; break
;
; 無条件に一番内側のループを脱出するようなコードを生成します.
;
; 生成される構造:
; jbra break
;
;----------------------------------------------------------------
; breakcc ループ脱出(条件付き)
;
; breakcc <命令>,…
;
; 条件が成立したら一番内側のループを脱出するようなコードを生成します.
;
; 生成される構造:
; <命令>,…
; JBcc break
;
; 条件になる命令は,
; <~>で囲って指定します.
; 複数の命令を記述できます(0個以上10個以下).
; 最後の命令を通過した直後の状態に従って分岐します.
;----------------------------------------------------------------
break .macro
.sizem sz
.if ~km_l_loop=0
.fail 1 ;breakすべきループがない
.exitm
.endif
jbra&sz ~km_a%~km_s_loop2
.endm
.irp %cc,t,f,hi,ls,cc,hs,cs,lo,ne,nz,eq,ze,vc,vs,pl,mi,ge,lt,gt,le
break%cc .macro op0,op1,op2,op3,op4,op5,op6,op7,op8,op9
.sizem sz
.if ~km_l_loop=0
.fail 1 ;breakすべきループがない
.exitm
.endif
op0
op1
op2
op3
op4
op5
op6
op7
op8
op9
.if '%cc'='t'
jbra&&sz ~km_a%~km_s_loop2
.elseif '%cc'='f'
.else
jb%cc&&sz ~km_a%~km_s_loop2
.endif
.endm
.endm
;----------------------------------------------------------------
; continue ループ条件へジャンプ
;
; continue
;
; 無条件に一番内側のループの条件判定にジャンプするようなコードを生成します.
;
; 生成される構造:
; JBRA continue
;----------------------------------------------------------------
; continuecc ループ条件へジャンプ(条件付き)
;
; continuecc <命令>,…
;
; 条件が成立したら一番内側のループの条件判定にジャンプするようなコードを生成します.
;
; 生成される構造:
; <命令>,…
; JBcc continue
;
; 条件になる命令は,
; <~>で囲って指定します.
; 複数の命令を記述できます(0個以上10個以下).
; 最後の命令を通過した直後の状態に従って分岐します.
;----------------------------------------------------------------
continue .macro
.sizem sz
.if ~km_l_loop=0
.fail 1 ;continueすべきループがない
.exitm
.endif
jbra&sz ~km_a%~km_s_loop1
.endm
.irp %cc,t,f,hi,ls,cc,hs,cs,lo,ne,nz,eq,ze,vc,vs,pl,mi,ge,lt,gt,le
continue%cc .macro op0,op1,op2,op3,op4,op5,op6,op7,op8,op9
.sizem sz
.if ~km_l_loop=0
.fail 1 ;continueすべきループがない
.exitm
.endif
op0
op1
op2
op3
op4
op5
op6
op7
op8
op9
.if '%cc'='t'
jbra&&sz ~km_a%~km_s_loop1
.elseif '%cc'='f'
.else
jb%cc&&sz ~km_a%~km_s_loop1
.endif
.endm
.endm
;----------------------------------------------------------------
.endif
.list